﻿using CIS.DB;
using CIS.Web.Common;
using CIS.Web.Models;
using CIS.Web.Properties;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Dynamic;
using System.Net.Mail;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace CIS.Web.Controllers
{
	[RoutePrefix("ProfileHotel")]
	public class ProfileHotelController : BaseDbController
	{
		public ActionResult Index()
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName);

			return View();
		}

		public async Task<JsonCamelCaseResult> GetData(int? page, int? rows, string sort, string order, ProfileHotelModel model)
		{
			int take = rows ?? ConstValues.DefaultGridRows;
			int skip = ((page ?? 1) - 1) * take;

			var sql = from profileHotelInfo in DbContext.ProfileHotelInfo.AsNoTracking()
					.Where(x => x.Creator == LoginUser.UserName)
				  group profileHotelInfo by new
				  {
					  conferenceId = profileHotelInfo.ConferenceId,
					  OrderNum = profileHotelInfo.OrderNum,
					  HotelId = profileHotelInfo.HotelId,
					  RoomType = profileHotelInfo.RoomType,
				  } into g
				  join conferenceMaster in DbContext.ConferenceMaster.AsNoTracking()
					on g.Key.conferenceId equals conferenceMaster.ID
				  join hotelMaster in DbContext.HotelMaster.AsNoTracking().Where(x => x.Status == ConstValues.Status.正常)
				       on g.Key.HotelId equals hotelMaster.ID
				  orderby g.Key.OrderNum descending, g.Max(x => x.DummyRoomNum) descending
				  select new
				  {
					  Status = g.Max(x => x.Status),
					  Currency = g.Max(x => x.Currency),
					  Fee = g.Sum(x => x.Fee),
					  Discount = g.Sum(x => x.Discount),
					  ConferenceId = g.Key.conferenceId,
					  OrderNum = g.Key.OrderNum,
					  Remark = g.Max(x => x.Remark),
					  Contact = g.Max(x => x.Contact),
					  ContactMobile = g.Max(x => x.ContactPhone),
					  ContactMail = g.Max(x => x.ContactMail),
					  ConferenceName = conferenceMaster.ConferenceName,
					  CreateDate = g.Max(x => x.CreateDate),
					  HomePageUrl = conferenceMaster.HomePageUrl,
					  ConferenceNickName = conferenceMaster.ConferenceNickName,
					  BenefitStartDate = conferenceMaster.BenefitStartDate,
					  BenefitEndDate = conferenceMaster.BenefitEndDate,
					  HotelName = hotelMaster.HotelName,
					  RoomType = g.Key.RoomType
				  };

			if (!string.IsNullOrWhiteSpace(model.ConferenceName) && model.ConferenceName != "")
			{
				sql = sql.Where(x => x.ConferenceName.Contains(model.ConferenceName));
			}

			int total = await sql.CountAsync();
			if (!string.IsNullOrEmpty(sort))
			{
				sql = sql.OrderBy(sort + ConstValues.chrSpace + order).Skip(skip).Take(take);
			}
			else
			{
				sql = sql.OrderBy(x => x.CreateDate).Skip(skip).Take(take);
			}

			var sqlResult = await sql.ToListAsync();

			var result = sqlResult.Select(x => new
			{
				Status = x.Status == ConstValues.Status.已预订 ? Resources.HasBooked : Resources.ScheduleStatusCancel,
				Currency = x.Currency,
				ConferenceId = x.ConferenceId,
				HotelName = x.HotelName,
				RoomType = x.RoomType,
				OrderNum = x.OrderNum,
				Remark = x.Remark,
				Contact = x.Contact,
				ContactMobile = x.ContactMobile,
				ContactMail = x.ContactMail,
				ConferenceName = x.ConferenceName,
				CreateDate = x.CreateDate,
				HomePageUrl = x.HomePageUrl,
				ConferenceNickName = x.ConferenceNickName,
				TotalFee = x.BenefitStartDate <= DateTime.Now && DateTime.Now <= x.BenefitEndDate ? x.Discount.ToString("N2") : x.Fee.ToString("N2")
			});

			return JsonCamelCase(new
			{
				Total = total,
				Rows = result,
			},
			JsonRequestBehavior.AllowGet);
		}

		public async Task<JsonCamelCaseResult> GetBookingDetail(string orderNum)
		{
			var sql = from profileHotelInfo in DbContext.ProfileHotelInfo.AsNoTracking()
					.Where(x => x.OrderNum == orderNum)
				  join conferenceMaster in DbContext.ConferenceMaster.AsNoTracking()
					 on profileHotelInfo.ConferenceId equals conferenceMaster.ID
				  orderby profileHotelInfo.DummyRoomNum descending, profileHotelInfo.CheckinDate descending
				  select new
				  {
					  Id = profileHotelInfo.ID,
					  HotelId = profileHotelInfo.HotelId,
					  Status = profileHotelInfo.Status,
					  Currency = profileHotelInfo.Currency,
					  Fee = profileHotelInfo.Fee,
					  Discount = profileHotelInfo.Discount,
					  Name1 = profileHotelInfo.Name1,
					  Name2 = profileHotelInfo.Name2,
					  CheckinDate = profileHotelInfo.CheckinDate,
					  CheckoutDate = profileHotelInfo.CheckoutDate,
					  RoomType = profileHotelInfo.RoomType,
					  RoomId = profileHotelInfo.RoomId,
					  IsCombine = profileHotelInfo.IsCombine,
					  BenefitStartDate = conferenceMaster.BenefitStartDate,
					  BenefitEndDate = conferenceMaster.BenefitEndDate,
					  IsInternational = conferenceMaster.IsInternational,
					  conferenceId = conferenceMaster.ID
				  };
			int total = await sql.CountAsync();
			var sqlResult = await sql.ToListAsync();

			var result = sqlResult.Select(x => new
			{
				Id = x.Id,
				Status = x.Status == ConstValues.Status.已预订 ? Resources.HasBooked : Resources.ScheduleStatusCancel,
				Currency = x.Currency,
				Name1 = x.Name1,
				Name2 = x.Name2,
				CheckinDate = x.IsInternational ? x.CheckinDate.ToString("MM/dd/yyyy") : x.CheckinDate.ToString("yyyy-MM-dd"),
				CheckoutDate = x.IsInternational ? x.CheckoutDate.ToString("MM/dd/yyyy") : x.CheckoutDate.ToString("yyyy-MM-dd"),
				BookingDate = (x.CheckoutDate - x.CheckinDate).Days,
				RoomType = x.RoomType,
				IsCombine = x.IsCombine ? Resources.Yes : Resources.No,
				Price = x.BenefitStartDate <= DateTime.Now && DateTime.Now <= x.BenefitEndDate ?
						DbContext.RoomMaster.FirstOrDefault(y => y.HotelId == x.HotelId && y.RoomType == x.RoomType && y.Currency == x.Currency && y.BookDate == x.CheckinDate).Price2.Value :
						DbContext.RoomMaster.FirstOrDefault(y => y.HotelId == x.HotelId && y.RoomType == x.RoomType && y.Currency == x.Currency && y.BookDate == x.CheckinDate).Price1.Value,
				conferenceId = x.conferenceId
			});

			return JsonCamelCase(new
			{
				Total = total,
				Rows = result,
			},
			JsonRequestBehavior.AllowGet);
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		public async Task<JsonResult> AddHotel(ProfileHotelModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var errorHotelName = string.Empty;
			var errorRoomTypeName = string.Empty;
			var errorDate = string.Empty;
			var isTrue = true;
			List<int> dummyList = new List<int>();

			var conferenceMaster = await DbContext.ConferenceMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.ID == model.ConferenceId);
			var mailHotel = new MailModel()
			{
				MailRemark = ConstValues.MailSubject.酒店修改,
				Language = conferenceMaster.IsInternational ? ConstValues.Language.En : ConstValues.Language.Cn,
				ConferenceId = conferenceMaster.ID,
				OrderNum = model.OrderNumber,
				HotelStatus = conferenceMaster.IsInternational ? "Reserved" : "已预订",
				DummyRoomNum = string.Empty,
				HotelName = string.Empty,
				RoomType = string.Empty,
				IsCombine = string.Empty,
				GuestName = string.Empty,
				CheckinDate = string.Empty,
				CheckoutDate = string.Empty,
			};

			using (var transaction = DbContext.Database.BeginTransaction())
			{
				model.TotalList.ForEach(x =>
				{
					var hotelMaster = DbContext.HotelMaster.AsNoTracking().FirstOrDefault(y => y.ID == x.HotelId);
					var roomMaster = DbContext.RoomMaster.AsNoTracking().FirstOrDefault(y => y.RoomType == x.RoomTypeId && y.HotelId == x.HotelId);

					if (roomMaster != null)
					{
						dummyList = Utility.GetDummyRoomNum(model.ConferenceId, x.nameList.Count(), dummyList);
						int differenceInDays = (Convert.ToDateTime(x.CheckoutDate) - Convert.ToDateTime(x.CheckinDate)).Days;
						int dummyIndex = 0;
						var guestName = string.Empty;

						//由多组两个名字组成的list
						x.nameList.ForEach(z =>
						{
							#region ProfileHotelInfo
							var profileHotelInfo = new ProfileHotelInfo
							{
								ID = Utility.GetTableId(ConstValues.TableName.ProfileHotelInfo),
								ConferenceId = x.ConferenceId,
								HotelId = x.HotelId,
								RoomType = roomMaster.RoomType,
								RoomId = string.Empty,
								IsCombine = x.NeedCombine == "true" ? true : false,
								Name1 = string.IsNullOrEmpty(z[0]) ? string.Empty : z[0].Trim(),
								Name2 = string.IsNullOrEmpty(z[1]) ? string.Empty : z[1].Trim(),
								CheckinDate = Convert.ToDateTime(x.CheckinDate),
								CheckoutDate = Convert.ToDateTime(x.CheckoutDate),
								OrderNum = model.OrderNumber,
								DummyRoomNum = dummyList[dummyIndex],
								Contact = x.ContactName,
								ContactPhone = x.ContactMobile,
								ContactMail = x.ContactMail,
								Remark = string.IsNullOrEmpty(x.Remark) ? string.Empty : x.Remark.Trim(),
								Currency = x.Currency,
								Fee = roomMaster.Price1.Value * differenceInDays,
								Discount = roomMaster.Price2.Value * differenceInDays,
								Creator = LoginUser.UserName,
								CreateDate = DateTime.Now,
								CreateIP = LoginUser.IP,
								UserName = LoginUser.UserName,
								Status = ConstValues.Status.已预订
							};
							DbContext.ProfileHotelInfo.Add(profileHotelInfo);
							#endregion

							dummyIndex++;
							DateTime startDate = Convert.ToDateTime(x.CheckinDate);
							DateTime endDate = Convert.ToDateTime(x.CheckoutDate);
							while (isTrue && startDate < endDate)
							{
								#region RoomMaster
								var room = DbContext.RoomMaster.FirstOrDefault(y => y.HotelId == x.HotelId && y.RoomType == roomMaster.RoomType &&
											y.BookDate == startDate && y.Currency == x.Currency);
								if (room == null || room.LeftRoomCount.Value < Convert.ToInt32(x.RoomNumber) || room.LeftBedCount < Convert.ToInt32(x.CheckinNumber))
								{
									isTrue = false;
									errorHotelName = DbContext.HotelMaster.AsNoTracking().FirstOrDefault(y => y.ID == x.HotelId)?.HotelName;
									errorRoomTypeName = roomMaster.RoomType;
									errorDate = startDate.ToString("yyyy-MM-dd");
									break;
								}

								//如果填了两个名字
								if (!string.IsNullOrEmpty(z[0]) && !string.IsNullOrEmpty(z[1]))
								{
									room.LeftRoomCount = room.LeftRoomCount.Value - 1;
									room.LeftBedCount = room.LeftBedCount.Value - room.RoomBedCount.Value;
								}
								else
								//只填了一个名字
								{
									//需要拼房
									if (x.NeedCombine == "true")
									{
										//床位数为1,即大床房
										if (room.RoomBedCount % 2 != 0)
										{
											room.LeftRoomCount = room.LeftRoomCount.Value - 1;
											room.LeftBedCount = room.LeftBedCount.Value - 1;
										}
										else
										{
											//剩余床位数为偶数
											if (room.LeftBedCount.Value % 2 == 0)
											{
												room.LeftBedCount = room.LeftBedCount.Value - 1;
											}
											else
											{
												room.LeftRoomCount = room.LeftRoomCount.Value - 1;
												room.LeftBedCount = room.LeftBedCount.Value - 1;
											}
										}
									}
									else
									{
										room.LeftRoomCount = room.LeftRoomCount.Value - 1;
										room.LeftBedCount = room.LeftBedCount.Value - room.RoomBedCount.Value;
									}
								}
								room.Updater = LoginUser.UserName;
								room.UpdateDate = DateTime.Now;
								room.UpdateIP = LoginUser.IP;
								#endregion

								#region CheckInInfo
								var checkinInfo = new CheckinInfo
								{
									ID = Utility.GetTableId(ConstValues.TableName.CheckinInfo),
									ConferenceId = x.ConferenceId,
									AttendenceId = profileHotelInfo.ID,
									HotelId = x.HotelId,
									RoomTypeId = room.ID,
									CheckinDate = startDate,
									Creator = LoginUser.UserName,
									CreateDate = DateTime.Now,
									CreateIP = LoginUser.IP,
									UserName = LoginUser.UserName,
								};
								DbContext.CheckinInfo.Add(checkinInfo);
								#endregion

								startDate = startDate.AddDays(1);
							}

							if (!string.IsNullOrEmpty(profileHotelInfo.Name1))
							{
								if (!string.IsNullOrEmpty(guestName))
								{
									guestName += conferenceMaster.IsInternational ? ConstValues.strComma : ConstValues.strCommaCn;
								}
								guestName += profileHotelInfo.Name1;
							}

							if (!string.IsNullOrEmpty(profileHotelInfo.Name2))
							{
								guestName += conferenceMaster.IsInternational ? ConstValues.strComma + profileHotelInfo.Name2 : ConstValues.strCommaCn + profileHotelInfo.Name2;
							}
						});

						mailHotel.DummyRoomNum = string.Join(ConstValues.strComma, dummyList);
						mailHotel.HotelName = hotelMaster.HotelName;
						mailHotel.RoomType = roomMaster.RoomType;
						mailHotel.IsCombine = x.NeedCombine == "true" ?
								(conferenceMaster.IsInternational ? "Yes" : "是") :
								(conferenceMaster.IsInternational ? "No" : "否");
						mailHotel.GuestName = guestName;
						mailHotel.CheckinDate = x.CheckinDate;
						mailHotel.CheckoutDate = x.CheckoutDate;
					}
				});

				if (isTrue)
				{
					await DbContext.SaveChangesAsync();

					#region SendMail
					var conferenceMailServerMaster = await DbContext.ConferenceMailServerMaster.AsNoTracking()
							.FirstOrDefaultAsync(x => x.Status == ConstValues.Status.正常 &&
								x.MailType == ConstValues.MailType.酒店交通服务邮箱 &&
								x.ConferenceId == model.ConferenceId);

					if (conferenceMailServerMaster == null)
					{
						conferenceMailServerMaster = await DbContext.ConferenceMailServerMaster.AsNoTracking()
								.FirstOrDefaultAsync(x => x.Status == ConstValues.Status.正常 &&
									x.MailType == ConstValues.MailType.会议邮箱 &&
									x.ConferenceId == model.ConferenceId);
					}

					if (conferenceMailServerMaster != null)
					{
						MailSender sender = new MailSender(conferenceMailServerMaster.MailServer);
						MailAddress from = new MailAddress(conferenceMailServerMaster.Mail);
						MailAddress to = new MailAddress(conferenceMailServerMaster.Mail);

						MailMessage message = Utility.GetMailContent(mailHotel);
						message.To.Add(to);

						if (!string.IsNullOrWhiteSpace(conferenceMailServerMaster.CcMail))
						{
							foreach (string cc in conferenceMailServerMaster.CcMail.Split(ConstValues.chrSemicolon))
							{
								if (!string.IsNullOrWhiteSpace(cc) && cc.Contains(ConstValues.chrAt))
								{
									message.Bcc.Add(new MailAddress(cc.Trim()));
								}
							}
						}

						var mailTask = Task.Run(() =>
						{
							sender.SendMail(from, message, conferenceMailServerMaster.Password);
						});
					}
					#endregion

					transaction.Commit();
				}
			}

			if (isTrue)
			{
				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(
							string.Format(Resources.MsgNotEnoughBookingRoom, errorDate, errorRoomTypeName)),
						JsonRequestBehavior.AllowGet);
			}
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		public async Task<JsonResult> EditHotel(ProfileHotelModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var errorHotelName = string.Empty;
			var errorRoomTypeName = string.Empty;
			var errorDate = string.Empty;
			var isTrue = true;
			
			var conferenceMaster = await DbContext.ConferenceMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.ID == model.ConferenceId);
			var mailHotel = new MailModel()
			{
				MailRemark = ConstValues.MailSubject.酒店修改,
				Language = conferenceMaster.IsInternational ? ConstValues.Language.En : ConstValues.Language.Cn,
				ConferenceId = conferenceMaster.ID,
				OrderNum = model.OrderNumber,
				HotelStatus = conferenceMaster.IsInternational ? "Reserved" : "已预订",
				DummyRoomNum = string.Empty,
				HotelName = string.Empty,
				RoomType = string.Empty,
				IsCombine = string.Empty,
				GuestName = string.Empty,
				CheckinDate = string.Empty,
				CheckoutDate = string.Empty,
			};

			using (var transaction = DbContext.Database.BeginTransaction())
			{
				model.TotalList.ForEach(x =>
				{
					var hotelMaster = DbContext.HotelMaster.AsNoTracking().FirstOrDefault(y => y.ID == x.HotelId);
					var roomMaster = DbContext.RoomMaster.AsNoTracking().FirstOrDefault(y => y.RoomType == x.RoomTypeId && y.HotelId == x.HotelId);

					if (roomMaster != null)
					{
						//由多组两个名字组成的list
						x.nameList.ForEach(z =>
						{
							var guestName = string.Empty;
							int differenceInDays = (Convert.ToDateTime(x.CheckoutDate) - Convert.ToDateTime(x.CheckinDate)).Days;
							var result = DbContext.ProfileHotelInfo.FirstOrDefault(y => y.ID == model.ProfileHotelId);

							DateTime tempCheckinDate = result.CheckinDate;
							DateTime tempCheckoutDate = result.CheckoutDate;
							while (tempCheckinDate < tempCheckoutDate)
							{
								#region RoomMaster
								//先把房间加回去
								var oldroom = DbContext.RoomMaster.FirstOrDefault(y => y.HotelId == result.HotelId && y.RoomType == result.RoomType &&
												y.BookDate == tempCheckinDate && y.Currency == result.Currency);
								if (oldroom != null)
								{
									if (result.IsCombine)
									{
										//需要拼房
										if (!string.IsNullOrEmpty(result.Name1) && !string.IsNullOrEmpty(result.Name2))
										{
											//如果填了两个名字
											oldroom.LeftRoomCount = oldroom.LeftRoomCount.Value + 1;
											oldroom.LeftBedCount = oldroom.LeftBedCount.Value + oldroom.RoomBedCount.Value;
										}
										else
										{
											if (oldroom.LeftBedCount.Value % 2 == 0)
											{
												oldroom.LeftRoomCount += 1;
											}
											oldroom.LeftBedCount += 1;
										}
									}
									else
									{
										//不需要拼房
										oldroom.LeftRoomCount += 1;
										oldroom.LeftBedCount += oldroom.RoomBedCount.Value;
									}
								}
								tempCheckinDate = tempCheckinDate.AddDays(1);
							}
							//再把checkininfo的原有数据删掉
							var oldCheckinInfoList = DbContext.CheckinInfo.Where(y => y.AttendenceId == result.ID).ToList();
							DbContext.CheckinInfo.RemoveRange(oldCheckinInfoList);

							//然后再把数据插回去
							DateTime startDate = Convert.ToDateTime(x.CheckinDate);
							DateTime endDate = Convert.ToDateTime(x.CheckoutDate);
							while (isTrue && startDate < endDate)
							{
								var room = DbContext.RoomMaster.FirstOrDefault(y => y.HotelId == x.HotelId && y.RoomType == roomMaster.RoomType &&
											y.BookDate == startDate && y.Currency == x.Currency);
								if (room == null || room.LeftRoomCount.Value < Convert.ToInt32(x.RoomNumber) || room.LeftBedCount < Convert.ToInt32(x.CheckinNumber))
								{
									isTrue = false;
									errorHotelName = DbContext.HotelMaster.AsNoTracking().FirstOrDefault(y => y.ID == x.HotelId)?.HotelName;
									errorRoomTypeName = roomMaster.RoomType;
									errorDate = startDate.ToString("yyyy-MM-dd");
									break;
								}

								//如果填了两个名字
								if (!string.IsNullOrEmpty(z[0]) && !string.IsNullOrEmpty(z[1]))
								{
									room.LeftRoomCount = room.LeftRoomCount.Value - 1;
									room.LeftBedCount = room.LeftBedCount.Value - room.RoomBedCount.Value;
								}
								else
								//只填了一个名字
								{
									//需要拼房
									if (x.NeedCombine == "true")
									{
										//床位数为1,即大床房
										if (room.RoomBedCount % 2 != 0)
										{
											room.LeftRoomCount = room.LeftRoomCount.Value - 1;
											room.LeftBedCount = room.LeftBedCount.Value - 1;
										}
										else
										{
											//剩余床位数为偶数
											if (room.LeftBedCount.Value % 2 == 0)
											{
												room.LeftBedCount = room.LeftBedCount.Value - 1;
											}
											else
											{
												room.LeftRoomCount = room.LeftRoomCount.Value - 1;
												room.LeftBedCount = room.LeftBedCount.Value - 1;
											}
										}
									}
									else
									{
										room.LeftRoomCount = room.LeftRoomCount.Value - 1;
										room.LeftBedCount = room.LeftBedCount.Value - room.RoomBedCount.Value;
									}
								}
								room.Updater = LoginUser.UserName;
								room.UpdateDate = DateTime.Now;
								room.UpdateIP = LoginUser.IP;
								#endregion

								#region CheckInInfo
								var checkinInfo = new CheckinInfo
								{
									ID = Utility.GetTableId(ConstValues.TableName.CheckinInfo),
									ConferenceId = x.ConferenceId,
									AttendenceId = result.ID,
									HotelId = x.HotelId,
									RoomTypeId = room.ID,
									CheckinDate = startDate,
									Creator = LoginUser.UserName,
									CreateDate = DateTime.Now,
									CreateIP = LoginUser.IP,
									UserName = LoginUser.UserName,
								};
								DbContext.CheckinInfo.Add(checkinInfo);
								#endregion

								startDate = startDate.AddDays(1);
							}

							//最后更新profile表的数据
							#region ProfileHotelInfo
							result.HotelId = x.HotelId;
							result.RoomType = roomMaster.RoomType;
							result.RoomId = string.Empty;
							result.IsCombine = x.NeedCombine == "true" ? true : false;
							result.Name1 = string.IsNullOrEmpty(z[0]) ? string.Empty : z[0].Trim();
							result.Name2 = string.IsNullOrEmpty(z[1]) ? string.Empty : z[1].Trim();
							result.CheckinDate = Convert.ToDateTime(x.CheckinDate);
							result.CheckoutDate = Convert.ToDateTime(x.CheckoutDate);
							result.Currency = x.Currency;
							result.Fee = roomMaster.Price1.Value * differenceInDays;
							result.Discount = roomMaster.Price2.Value * differenceInDays;
							result.UserName = LoginUser.UserName;
							result.Status = ConstValues.Status.已预订;
							result.Contact = x.ContactName.Trim();
							result.ContactMail = x.ContactMail.Trim();
							result.ContactPhone = x.ContactMobile.Trim();
							result.Remark = string.IsNullOrEmpty(x.Remark) ? string.Empty : x.Remark.Trim();

							#endregion

							if (!string.IsNullOrEmpty(result.Name1))
							{
								guestName += result.Name1;
							}

							if (!string.IsNullOrEmpty(result.Name2))
							{
								guestName += conferenceMaster.IsInternational ? ConstValues.strComma + result.Name2 : ConstValues.strCommaCn + result.Name2;
							}

							mailHotel.DummyRoomNum = result.DummyRoomNum.ToString();
							mailHotel.HotelName = hotelMaster.HotelName;
							mailHotel.RoomType = roomMaster.RoomType;
							mailHotel.IsCombine = x.NeedCombine == "true" ?
									(conferenceMaster.IsInternational ? "Yes" : "是") :
									(conferenceMaster.IsInternational ? "No" : "否");
							mailHotel.GuestName = guestName;
							mailHotel.CheckinDate = x.CheckinDate;
							mailHotel.CheckoutDate = x.CheckoutDate;
						});
					}
				});

				if (isTrue)
				{
					await DbContext.SaveChangesAsync();

					#region SendMail
					var conferenceMailServerMaster = await DbContext.ConferenceMailServerMaster.AsNoTracking()
							.FirstOrDefaultAsync(x => x.Status == ConstValues.Status.正常 &&
								x.MailType == ConstValues.MailType.酒店交通服务邮箱 &&
								x.ConferenceId == model.ConferenceId);

					if (conferenceMailServerMaster == null)
					{
						conferenceMailServerMaster = await DbContext.ConferenceMailServerMaster.AsNoTracking()
								.FirstOrDefaultAsync(x => x.Status == ConstValues.Status.正常 &&
									x.MailType == ConstValues.MailType.会议邮箱 &&
									x.ConferenceId == model.ConferenceId);
					}

					if (conferenceMailServerMaster != null)
					{
						MailSender sender = new MailSender(conferenceMailServerMaster.MailServer);
						MailAddress from = new MailAddress(conferenceMailServerMaster.Mail);
						MailAddress to = new MailAddress(conferenceMailServerMaster.Mail);

						MailMessage message = Utility.GetMailContent(mailHotel);
						message.To.Add(to);

						if (!string.IsNullOrWhiteSpace(conferenceMailServerMaster.CcMail))
						{
							foreach (string cc in conferenceMailServerMaster.CcMail.Split(ConstValues.chrSemicolon))
							{
								if (!string.IsNullOrWhiteSpace(cc) && cc.Contains(ConstValues.chrAt))
								{
									message.Bcc.Add(new MailAddress(cc.Trim()));
								}
							}
						}

						var mailTask = Task.Run(() =>
						{
							sender.SendMail(from, message, conferenceMailServerMaster.Password);
						});
					}
					#endregion

					transaction.Commit();
				}
			}

			if (isTrue)
			{
				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(
						string.Format(Resources.MsgNotEnoughBookingRoom, errorDate, errorRoomTypeName)),
					JsonRequestBehavior.AllowGet);
			}
		}

		public async Task<JsonCamelCaseResult> GetHotelDetail(string id)
		{
			var data = await DbContext.ProfileHotelInfo.AsNoTracking().FirstOrDefaultAsync(x => x.ID == id);

			if (data != null)
			{
				var conferenceMaster = await DbContext.ConferenceMaster.AsNoTracking().FirstOrDefaultAsync(x => x.ID == data.ConferenceId);
				var roomMaster = await DbContext.RoomMaster.AsNoTracking().FirstOrDefaultAsync(x => x.HotelId == data.HotelId &&
							x.RoomType == data.RoomType && x.Currency == data.Currency);
				var result = new
				{
					HotelId = data.HotelId,
					RoomType = data.RoomType,
					CheckinDate = conferenceMaster.IsInternational ?
								data.CheckinDate.ToString("MM/dd/yyyy") :
								data.CheckinDate.ToString("yyyy-MM-dd"),
					CheckoutDate = conferenceMaster.IsInternational ?
								data.CheckoutDate.ToString("MM/dd/yyyy") :
								data.CheckoutDate.ToString("yyyy-MM-dd"),
					Name1 = data.Name1,
					Name2 = data.Name2,
					IsCombine = data.IsCombine,
					Currency = data.Currency,
					ConferenceId = data.ConferenceId,
					Contact = data.Contact,
					ContactMail = data.ContactMail,
					ContactPhone = data.ContactPhone,
					Remark = data.Remark,
					CheckinNumber = (string.IsNullOrEmpty(data.Name1) ? 0 : 1) +
								     (string.IsNullOrEmpty(data.Name2) ? 0 : 1),
					Price = conferenceMaster.BenefitStartDate <= DateTime.Now && DateTime.Now <= conferenceMaster.BenefitEndDate ?
							roomMaster.Price2.Value.ToString("N2") :
							roomMaster.Price1.Value.ToString("N2"),
				};

				return JsonCamelCase(Utility.CreateSuccessJsonResult(string.Empty, result),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		public async Task<JsonResult> CancelBooking(ProfileHotelModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var result = await DbContext.ProfileHotelInfo
					.FirstOrDefaultAsync(x => x.ID == model.ProfileHotelId);

			if (result == null)
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}

			using (var transaction = DbContext.Database.BeginTransaction())
			{
				result.Status = ConstValues.Status.已取消;

				var oldCheckinInfoList = DbContext.CheckinInfo.Where(y => y.AttendenceId == model.ProfileHotelId).ToList();
				DbContext.CheckinInfo.RemoveRange(oldCheckinInfoList);

				DateTime tempCheckinDate = result.CheckinDate;
				DateTime tempCheckoutDate = result.CheckoutDate;
				while (tempCheckinDate < tempCheckoutDate)
				{
					#region RoomMaster
					//把房间加回去
					var roomMaster = DbContext.RoomMaster.FirstOrDefault(y => y.HotelId == result.HotelId && y.RoomType == result.RoomType &&
								y.BookDate == tempCheckinDate && y.Currency == result.Currency);
					if (roomMaster != null)
					{
						if (result.IsCombine)
						{
							//需要拼房
							if (!string.IsNullOrEmpty(result.Name1) && !string.IsNullOrEmpty(result.Name2))
							{
								//如果填了两个名字
								roomMaster.LeftRoomCount = roomMaster.LeftRoomCount.Value + 1;
								roomMaster.LeftBedCount = roomMaster.LeftBedCount.Value + roomMaster.RoomBedCount.Value;
							}
							else
							{
								if (roomMaster.LeftBedCount.Value % 2 == 0)
								{
									roomMaster.LeftRoomCount += 1;
								}
								roomMaster.LeftBedCount += 1;
							}
						}
						else
						{
							//不需要拼房
							roomMaster.LeftRoomCount += 1;
							roomMaster.LeftBedCount += roomMaster.RoomBedCount.Value;
						}
					}
					tempCheckinDate = tempCheckinDate.AddDays(1);
					#endregion
				}
				await DbContext.SaveChangesAsync();

				#region SendMail
				var conferenceMailServerMaster = await DbContext.ConferenceMailServerMaster.AsNoTracking()
						.FirstOrDefaultAsync(x => x.Status == ConstValues.Status.正常 &&
							x.MailType == ConstValues.MailType.酒店交通服务邮箱 &&
							x.ConferenceId == model.ConferenceId);

				if (conferenceMailServerMaster == null)
				{
					conferenceMailServerMaster = await DbContext.ConferenceMailServerMaster.AsNoTracking()
							.FirstOrDefaultAsync(x => x.Status == ConstValues.Status.正常 &&
								x.MailType == ConstValues.MailType.会议邮箱 &&
								x.ConferenceId == model.ConferenceId);
				}

				if (conferenceMailServerMaster != null)
				{
					var conferenceMaster = await DbContext.ConferenceMaster.AsNoTracking()
							.FirstOrDefaultAsync(x => x.ID == model.ConferenceId);

					MailSender sender = new MailSender(conferenceMailServerMaster.MailServer);
					MailAddress from = new MailAddress(conferenceMailServerMaster.Mail);
					MailAddress to = new MailAddress(conferenceMailServerMaster.Mail);

					var guestName = result.Name1;
					if (!string.IsNullOrEmpty(result.Name2))
					{
						guestName += conferenceMaster.IsInternational ? ConstValues.strComma + result.Name2 : ConstValues.strCommaCn + result.Name2;
					}

					var hotelMaster = DbContext.HotelMaster.AsNoTracking().FirstOrDefault(y => y.ID == result.HotelId);

					MailMessage message = Utility.GetMailContent(new MailModel
					{
						MailRemark = ConstValues.MailSubject.酒店修改,
						Language = conferenceMaster.IsInternational ? ConstValues.Language.En : ConstValues.Language.Cn,
						ConferenceId = conferenceMaster.ID,
						OrderNum = result.OrderNum,
						HotelStatus = conferenceMaster.IsInternational ? "Canceled" : "已取消",
						DummyRoomNum = result.DummyRoomNum.ToString(),
						HotelName = hotelMaster.HotelName,
						RoomType = result.RoomType,
						IsCombine = result.IsCombine ?
							(conferenceMaster.IsInternational ? "Yes" : "是") :
							(conferenceMaster.IsInternational ? "No" : "否"),
						GuestName = guestName,
						CheckinDate = conferenceMaster.IsInternational ? result.CheckinDate.ToString("MM/dd/yyyy") : result.CheckinDate.ToString("yyyy-MM-dd"),
						CheckoutDate = conferenceMaster.IsInternational ? result.CheckoutDate.ToString("MM/dd/yyyy") : result.CheckoutDate.ToString("yyyy-MM-dd"),
					});
					message.To.Add(to);

					if (!string.IsNullOrWhiteSpace(conferenceMailServerMaster.CcMail))
					{
						foreach (string cc in conferenceMailServerMaster.CcMail.Split(ConstValues.chrSemicolon))
						{
							if (!string.IsNullOrWhiteSpace(cc) && cc.Contains(ConstValues.chrAt))
							{
								message.Bcc.Add(new MailAddress(cc.Trim()));
							}
						}
					}

					var mailTask = Task.Run(() =>
					{
						sender.SendMail(from, message, conferenceMailServerMaster.Password);
					});
				}
				#endregion

				transaction.Commit();
			}

			return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessCancel),
					JsonRequestBehavior.AllowGet);
		}

		public async Task<JsonCamelCaseResult> GetContact()
		{
			var sysUserMaster = await DbContext.SysUserMaster.AsNoTracking().FirstOrDefaultAsync(x => x.ID == LoginUser.UserID);

			if (sysUserMaster != null)
			{
				var data = new
				{
					FullName = sysUserMaster == null ? string.Empty : sysUserMaster.FullName,
					Mail = sysUserMaster == null ? string.Empty : sysUserMaster.Mail,
					Mobile = sysUserMaster == null ? string.Empty : sysUserMaster.Mobile
				};
				return JsonCamelCase(Utility.CreateSuccessJsonResult(string.Empty, data),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(),
						JsonRequestBehavior.AllowGet);
			}
		}
	}
}